package com.youbug.mall.product_pms.service.impl;

import com.youbug.mall.product_pms.constant.ProductConstant;
import com.youbug.mall.product_pms.entity.*;
import com.youbug.mall.product_pms.mapper.PmsAttrMapper;
import com.youbug.mall.product_pms.service.IAttrGroupService;
import com.youbug.mall.product_pms.service.ICategoryService;
import com.youbug.mall.product_pms.service.IPmsAttrAttrgroupRelationService;
import com.youbug.mall.product_pms.service.IPmsAttrService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.youbug.mall.product_pms.entity.PmsAttr;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import com.youbug.common.vo.QueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品属性 服务实现类
 * </p>
 *
 * @author youbug
 * @since 2024-04-09
 */
@Service
public class PmsAttrServiceImpl extends ServiceImpl<PmsAttrMapper, PmsAttr> implements IPmsAttrService {

    @Autowired
    private IPmsAttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private IAttrGroupService attrGroupService;

    @Override
    public IPage<PmsAttr> getPmsAttrPage(QueryVo<PmsAttr> queryVo) {

        Page<PmsAttr> paramPage = new Page<>();

        paramPage.setCurrent(queryVo.getCurrentPage());

        paramPage.setSize(queryVo.getPageSize());

        QueryWrapper<PmsAttr> wrapper = new QueryWrapper<>();

        PmsAttr pmsAttr = queryVo.getPayload();

        if(!ObjectUtils.isEmpty(pmsAttr)){
            if(pmsAttr.getAttrType() != null){
                wrapper.eq("attr_type", pmsAttr.getAttrType());
            }
            if(StringUtils.hasText(pmsAttr.getAttrName())){
                wrapper.eq("attr_name", pmsAttr.getAttrName());
            }
            if(pmsAttr.getCatalogId() != null){
                wrapper.eq("catalog_id", pmsAttr.getCatalogId());
            }
        }
        if(!ObjectUtils.isEmpty(queryVo.getStartTime())){
            wrapper.gt("create_time", queryVo.getStartTime());
        }
        if(!ObjectUtils.isEmpty(queryVo.getEndTime())){
            wrapper.lt("create_time", queryVo.getEndTime());
        }
        wrapper.orderByDesc("create_time");

        Page<PmsAttr> page = this.page(paramPage, wrapper);

        List<PmsAttr> records = page.getRecords();

        if(!CollectionUtils.isEmpty(records)){
            Map<Long, PmsAttrGroup> attrGroupMap = null;
            Map<Long, Long> relationMap = null;
            if(pmsAttr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
                List<Long> attrIds = page.getRecords().stream().map(PmsAttr::getAttrId).collect(Collectors.toList());

                List<PmsAttrAttrgroupRelation> relations = attrAttrgroupRelationService
                        .list(new QueryWrapper<PmsAttrAttrgroupRelation>().select("attr_id","attr_group_id").in("attr_id", attrIds));

                relationMap = relations.stream().filter(e->{return e.getAttrGroupId()!=null;})
                        .collect(Collectors.toMap(PmsAttrAttrgroupRelation::getAttrId, PmsAttrAttrgroupRelation::getAttrGroupId,(v,v1)->v));

                List<Long> attrGroupIds = relations.stream().map(PmsAttrAttrgroupRelation::getAttrGroupId).collect(Collectors.toList());

                List<PmsAttrGroup> attrGroups = attrGroupService.list(new QueryWrapper<PmsAttrGroup>()
                        .select("attr_group_id", "attr_group_name").in("attr_group_id", attrGroupIds));

               attrGroupMap = attrGroups.stream().collect(Collectors.toMap(PmsAttrGroup::getAttrGroupId, e -> e, (v, v1)-> v));
            }
            List<Long> catalogIds = page.getRecords().stream().map(PmsAttr::getCatalogId).collect(Collectors.toList());

            List<PmsCategory> categories = categoryService.list(new QueryWrapper<PmsCategory>().select("cat_id","name").in("cat_id", catalogIds));

            Map<Long, PmsCategory> categoryMap = categories.stream().collect(Collectors.toMap(PmsCategory::getCatId, e -> e, (v, v1) -> v));
            Map<Long, PmsAttrGroup> finalAttrGroupMap = attrGroupMap;
            Map<Long, Long> finalRelationMap = relationMap;
            records.forEach(record->{
                if(finalAttrGroupMap != null){
                    PmsAttrGroup group = finalAttrGroupMap.get(finalRelationMap.get(record.getAttrId()));

                    record.setGroupName(group==null ? null : group.getAttrGroupName());
                }
                PmsCategory category = categoryMap.get(record.getCatalogId());

                record.setCatalogName(category==null ? null : category.getName());
            });
        }
        return page;
    }

    @Override
    @Transactional(transactionManager = "transactionManagerPms", rollbackFor = Exception.class)
    public boolean saveAttr(PmsAttr pmsAttr) {
        boolean save = this.save(pmsAttr);
        if(pmsAttr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && pmsAttr.getAttrGroupId() != null) {
            PmsAttrAttrgroupRelation relation = new PmsAttrAttrgroupRelation();
            relation.setAttrId(pmsAttr.getAttrId());
            relation.setAttrGroupId(pmsAttr.getAttrGroupId());

            boolean save1 = attrAttrgroupRelationService.save(relation);
            return save&&save1;
        }
        return save;
    }

    @Override
    public PmsAttr getPmsAttrById(Integer id) {
        PmsAttr pmsAttr = this.getById(id);
        if(pmsAttr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            PmsAttrAttrgroupRelation relation = attrAttrgroupRelationService
                    .getOne(new QueryWrapper<PmsAttrAttrgroupRelation>().eq("attr_id", pmsAttr.getAttrId()));
            if (relation != null) {
                pmsAttr.setAttrGroupId(relation.getAttrGroupId());
            }
        }
        return pmsAttr;
    }

    @Override
    @Transactional(transactionManager = "transactionManagerPms", rollbackFor = Exception.class)
    public boolean updatePmsAttrById(PmsAttr pmsAttr) {
        boolean update = this.updateById(pmsAttr);
        if(pmsAttr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            PmsAttrAttrgroupRelation relation = new PmsAttrAttrgroupRelation();
            relation.setAttrId(pmsAttr.getAttrId());
            relation.setAttrGroupId(pmsAttr.getAttrGroupId());

            int count = attrAttrgroupRelationService.count(new QueryWrapper<PmsAttrAttrgroupRelation>().eq("attr_id", pmsAttr.getAttrId()));
            boolean updateRealtion;
            if (count > 0) {
                updateRealtion = attrAttrgroupRelationService
                        .update(relation, new QueryWrapper<PmsAttrAttrgroupRelation>().eq("attr_id", pmsAttr.getAttrId()));
            } else {
                updateRealtion = attrAttrgroupRelationService.save(relation);
            }
            return update&&updateRealtion;
        }
        return update;
    }

    @Override
    @Transactional(transactionManager = "transactionManagerPms", rollbackFor = Exception.class)
    public boolean removePmsAttrById(Integer id) {
        PmsAttr pmsAttr = this.getById(id);
        if(pmsAttr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
           attrAttrgroupRelationService.remove(new QueryWrapper<PmsAttrAttrgroupRelation>()
                    .eq("attr_id", id)
                    .eq("attr_group_id", pmsAttr.getAttrGroupId()));
        }
        boolean remove = this.removeById(id);
        return remove;
    }

    @Override
    public List<PmsAttr> getRelationAttrs(Long attrGroupId) {

            List<PmsAttrAttrgroupRelation> relations = attrAttrgroupRelationService.list(new QueryWrapper<PmsAttrAttrgroupRelation>()
                    .eq("attr_group_id", attrGroupId));
            if(relations != null && relations.size() > 0){

                List<Long> attrIds = relations.stream().map(PmsAttrAttrgroupRelation::getAttrId).collect(Collectors.toList());

                List<PmsAttr> attrs = this.listByIds(attrIds);

                return attrs;
            }
        return null;
    }
    /*
    查出需要检索的属性
     */
    @Override
    public List<Long> selectSearchAttrs(List<Long> baseAttrIds) {

        List<PmsAttr> attrs = this.list(new QueryWrapper<PmsAttr>().select("attr_id").eq("search_type",1)
                .in("attr_id", baseAttrIds));
        List<Long> list = attrs.stream().map(PmsAttr::getAttrId).collect(Collectors.toList());
        return list;
    }
}
